Skip to content

feat(sdk): functional baseURL and fetch override on chat transports#3655

Merged
ericallam merged 4 commits into
mainfrom
feat/chat-transport-base-url-fetch
May 18, 2026
Merged

feat(sdk): functional baseURL and fetch override on chat transports#3655
ericallam merged 4 commits into
mainfrom
feat/chat-transport-base-url-fetch

Conversation

@ericallam
Copy link
Copy Markdown
Member

Summary

TriggerChatTransport, AgentChat, and chat.createStartSessionAction now accept a string-or-function baseURL so callers can route per endpoint — e.g. .in/append through a trusted edge proxy while keeping .out SSE direct. The same surfaces add a fetch override for header injection, custom retries, or proxy rewrites that go beyond URL routing. SSE GETs are covered too via a new fetchClient option on SSEStreamSubscription.

// TriggerChatTransport / AgentChat — endpoints: "in" | "out"
baseURL: ({ endpoint }) =>
  endpoint === "out" ? DIRECT : PROXY,

fetch: (url, init, ctx) => {
  init.headers = new Headers(init.headers);
  init.headers.set("traceparent", currentTraceparent());
  return globalThis.fetch(url, init);
},

// chat.createStartSessionAction — endpoints: "sessions" | "auth"
chat.createStartSessionAction("my-agent", {
  baseURL: ({ endpoint }) => (endpoint === "sessions" ? PROXY : DIRECT),
});

streamBaseURL on TriggerChatTransport is kept as a backwards-compat alias and continues to win for the "out" endpoint when set. Plain-string baseURL still applies to every endpoint, matching prior behavior.

Test plan

  • chat.test.ts — two new cases covering function-form baseURL and the fetch override (40 tests, all green).
  • Drove the full flow against a Cloudflare Worker proxy in front of a chat agent: appends and session-create rewritten through the worker, SSE direct, agent received the injected clientData typed via clientDataSchema.

TriggerChatTransport, AgentChat, and chat.createStartSessionAction now
accept a string-or-function baseURL so callers can route per endpoint —
e.g. .in/append through a trusted edge proxy while keeping .out SSE
direct. The same surfaces add a fetch override for header injection,
custom retries, or proxy rewrites that go beyond URL routing; SSE GETs
are covered via a new fetchClient option on SSEStreamSubscription.

streamBaseURL on TriggerChatTransport is kept as a backwards-compat
alias and continues to win for the "out" endpoint when set. Plain-string
baseURL still applies to every endpoint, matching prior behavior.
@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented May 18, 2026

⚠️ No Changeset found

Latest commit: 418965f

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 18, 2026

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 921bda12-69f6-42bd-94d7-88f8c951109d

📥 Commits

Reviewing files that changed from the base of the PR and between e8d005a and 418965f.

📒 Files selected for processing (1)
  • packages/trigger-sdk/src/v3/chat-client.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/trigger-sdk/src/v3/chat-client.ts
📜 Recent review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (30)
  • GitHub Check: webapp / 🧪 Unit Tests: Webapp (7, 8)
  • GitHub Check: internal / 🧪 Unit Tests: Internal (8, 8)
  • GitHub Check: internal / 🧪 Unit Tests: Internal (4, 8)
  • GitHub Check: webapp / 🧪 Unit Tests: Webapp (3, 8)
  • GitHub Check: webapp / 🧪 Unit Tests: Webapp (4, 8)
  • GitHub Check: webapp / 🧪 Unit Tests: Webapp (2, 8)
  • GitHub Check: webapp / 🧪 Unit Tests: Webapp (1, 8)
  • GitHub Check: webapp / 🧪 Unit Tests: Webapp (8, 8)
  • GitHub Check: sdk-compat / Node.js 20.20 (ubuntu-latest)
  • GitHub Check: internal / 🧪 Unit Tests: Internal (6, 8)
  • GitHub Check: webapp / 🧪 Unit Tests: Webapp (5, 8)
  • GitHub Check: sdk-compat / Node.js 22.12 (ubuntu-latest)
  • GitHub Check: internal / 🧪 Unit Tests: Internal (2, 8)
  • GitHub Check: internal / 🧪 Unit Tests: Internal (5, 8)
  • GitHub Check: internal / 🧪 Unit Tests: Internal (1, 8)
  • GitHub Check: internal / 🧪 Unit Tests: Internal (7, 8)
  • GitHub Check: internal / 🧪 Unit Tests: Internal (3, 8)
  • GitHub Check: webapp / 🧪 Unit Tests: Webapp (6, 8)
  • GitHub Check: e2e / 🧪 CLI v3 tests (ubuntu-latest - pnpm)
  • GitHub Check: e2e-webapp / 🧪 E2E Tests: Webapp
  • GitHub Check: e2e / 🧪 CLI v3 tests (ubuntu-latest - npm)
  • GitHub Check: e2e / 🧪 CLI v3 tests (windows-latest - npm)
  • GitHub Check: typecheck / typecheck
  • GitHub Check: sdk-compat / Bun Runtime
  • GitHub Check: sdk-compat / Deno Runtime
  • GitHub Check: sdk-compat / Cloudflare Workers
  • GitHub Check: e2e / 🧪 CLI v3 tests (windows-latest - pnpm)
  • GitHub Check: packages / 🧪 Unit Tests: Packages (1, 1)
  • GitHub Check: audit
  • GitHub Check: Analyze (javascript-typescript)

Walkthrough

This PR extends the chat routing infrastructure to support custom per-endpoint base URLs and fetch overrides. SSEStreamSubscription gains an optional fetchClient parameter for custom fetch implementations. Three chat modules—ai.ts (session start), chat-client.ts (AgentChat), and chat.ts (TriggerChatTransport)—now export endpoint types and accept baseURL (string or resolver function) and fetch (override hook) options. All three replace prior ApiClient usage with direct fetch calls via new appendInputChunk and resolveBaseURL helpers that respect the overrides. SSE subscriptions pass derived fetchClient wrappers into SSEStreamSubscription to apply routing to streaming requests. Tests verify endpoint-aware routing and fetch override invocation.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 20.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Description check ❓ Inconclusive The description covers the summary, test plan, and changelog, but is missing the required checklist and issue reference sections from the template. Add the checklist items and issue reference (Closes #) to match the template structure and document testing steps completed.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately and concisely describes the main change: adding functional (string-or-function) baseURL and fetch override support to chat transports.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/chat-transport-base-url-fetch

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Reference example for the trusted-edge-signals pattern. A minimal
Cloudflare Worker (references/ai-chat/cf-worker) rewrites POST
/api/v1/sessions and POST /realtime/v1/sessions/{id}/in/append to
inject server-trusted bot-management signals into payload.metadata.__cf
before forwarding upstream. The new cfTrustTestAgent declares the
namespace in clientDataSchema and echoes the values back so the
round-trip is visible in the streamed response.

cf-worker README walks through the wire-up and shows the function-form
baseURL snippet for routing .out SSE direct while .in/append flows
through the worker.
coderabbitai[bot]

This comment was marked as resolved.

…est input in SSE wrapper

When chat.createStartSessionAction was given a baseURL or fetch
override, the inline POSTs for /api/v1/sessions and
/api/v1/auth/jwt/claims forgot to forward apiClientManager.branchName as
the x-trigger-branch header. Callers running against a preview branch
(via TRIGGER_PREVIEW_BRANCH or VERCEL_GIT_COMMIT_REF) would route to
the wrong environment in override mode. Extracted the header builder
to a shared helper.

The SSE fetch wrappers in TriggerChatTransport.subscribeToSessionStream
and AgentChat.subscribeToSessionStream cast to typeof fetch but coerced
non-string input via .toString(), which yields "[object Request]" on
Request objects and discards the Request's intrinsic method/headers/
signal. Replaced the coercion with explicit branches for string, URL,
and Request — Request inputs now extract url + init properly with any
caller-provided init taking precedence (matches fetch(Request, init)
semantics).
@ericallam ericallam marked this pull request as ready for review May 18, 2026 14:37
devin-ai-integration[bot]

This comment was marked as resolved.

When AgentChat.appendInputChunk fails non-2xx after the inline-POST
refactor, it was throwing a plain Error. Callers of sendRaw, sendMessage,
sendHandover, and sendHandoverSkip inspecting error.name ===
"TriggerApiError" or error.status saw "Error" / undefined instead of
the values the prior ApiClient/zodfetch path produced. Synthesize the
same shape here so the public error contract is preserved. Matches the
equivalent fix already applied to TriggerChatTransport.
@ericallam ericallam merged commit 427d9e0 into main May 18, 2026
45 checks passed
@ericallam ericallam deleted the feat/chat-transport-base-url-fetch branch May 18, 2026 15:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants